/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package collision;



import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import util.*;

/**
 *
 * @author debci
 */
public class Generador {
    
    private boolean acabado = false;
    private BigInteger porcentage = BigInteger.valueOf(99);
    private static BigInteger percent = null;
    private static BigInteger posibles = null;
    private static BigInteger posiblesEstatico = null;
    private static int contadorcillo = 95;
    private static int barritas = 1;
    private static boolean conseguido = false;

public Generador() {

}
public void getAllCombo(String hash, String algoritmo, char[] dicionario, int length) {
        String resultado = null;
        String match = hash;
        System.out.println("[+]Procediendo a crackear el hash:\n" + hash);
        char[] mapaChars = dicionario;
        //char[] mapaChars = {'A','B','C','D','E','F','$',' '};
        int longitud = length;
        BigInteger largo = BigInteger.valueOf(mapaChars.length);
        posibles = largo.pow(longitud);
        posiblesEstatico = posibles;
        
        System.out.println("[!]Hay " + posibles + " combinaciones posibles.");
        System.out.println("          [--25---50---75---100]");
        System.out.print("Progreso: [=");
        char[] combinacion = new char[longitud];

        int[] indice = new int[longitud];
        Crono tempo = new Crono();
        tempo.setPriority(Thread.MAX_PRIORITY);
        tempo.start();

        while(!acabado)
        {
          try{
          for(int x = 0; x < indice.length; x++) {
           if(!(x==(indice.length))) {
                  if((indice[x] == (mapaChars.length))) {
                    indice[x] = 0;
                    indice[x+1]++;
                  }
                }else{
                  indice[x] = 0;
                }
          }
          //Asignamos la combinación numérica al vector de caracteres
          for(int h = 0; h < longitud; h++) {
              combinacion[h] = mapaChars[indice[h]];
          }

          char[] resultadoTemporal = new char[longitud];
                System.arraycopy(combinacion, 0, resultadoTemporal, 0, combinacion.length);

          String resultadoFinal = new String(resultadoTemporal);
          String cadenaFormateada = new String();
          /* Formateamos la cadena quitandole los espacios existentes para */
          /* generar todas las formas posibles                             */
          for (int x = 0; x < resultadoFinal.length(); x++) {
               if (resultadoFinal.charAt(x) != '$') {
                 cadenaFormateada += resultadoFinal.charAt(x);
              }
          }
          String resultadoEncriptado = Generador.encriptaMD5(cadenaFormateada,algoritmo);
          
          percent = Arithmetic.getPercent(posiblesEstatico, porcentage);
          
          if(percent.compareTo(posibles) == 1) {
              porcentage = porcentage.subtract(BigInteger.ONE);
          }
             if(porcentage.equals(BigInteger.valueOf(contadorcillo))) {
                  System.out.print("=");
                  barritas = barritas+1;
                  contadorcillo = contadorcillo-5;
              }
          
                //System.out.println(cadenaFormateada + " =======> " + resultadoEncriptado);
              
              
                

          if(resultadoEncriptado.equals(match))
          {
              resultado = resultadoTemporal.toString();
              int barritasRestantes = 20-barritas;
              for(int p = 0; p < barritasRestantes; p++) {
                  System.out.print("=");
              }
              System.out.print("]\n");
              System.out.println("\n[+]Hash crackeada con exito!\n[+]Valor desencriptado: " + (resultadoFinal.replace('$',' ')).trim()+"\n\n");
              conseguido = true;
              tempo.stopCrono(tempo);
              Thread.sleep(10000);
              break;
          }

          indice[0]++;
          //System.out.println("[!]Quedan " + posibles + " combinaciones.");

          if(posibles.equals(BigInteger.ONE)) {
              acabado = true;
          }

            posibles = posibles.subtract(BigInteger.ONE);

        }   catch (InterruptedException ex) {
                Logger.getLogger(Generador.class.getName()).log(Level.SEVERE, null, ex);
            }catch(ArrayIndexOutOfBoundsException e){

        }
    }
        if(!conseguido) {
            try {
                System.out.println("\n[-]No se ha podido crackear la hash...");
                System.out.println("[!]Puede intentarlo de nuevo con la opcion 'Crackeo personalizado'\n\n[!]Volviendo al menu inicial...\n\n\n");
                Thread.sleep(10000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Generador.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
public static String encriptaMD5(String toEnc, String algoritmo)
    {

        MessageDigest mdEnc = null;
        try {
            mdEnc = MessageDigest.getInstance(algoritmo); // Encryption algorithm

        } catch (NoSuchAlgorithmException ex) {
            System.err.println("[-]No se ha encontrado el algoritmo.");
        }

            mdEnc.update(toEnc.getBytes(), 0, toEnc.length());

            String md5 = new BigInteger(1, mdEnc.digest()).toString(16);
            return md5;
    }
}